home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / redo / redoLHash.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  13.1 KB  |  458 lines

  1. /*
  2.  *    $RCSfile: redoLHash.C,v $
  3.  *    $Revision: 1.1.1.1 $
  4.  *    $Date: 1996/05/04 21:55:58 $
  5.  */
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37. #include "BTREEPAGE.h"
  38. #include "LH_Log.h"
  39. #include "bf_macro.h"
  40. #include "redo_intfuncs.h"
  41.  
  42.  
  43. #ifdef DEBUG
  44. extern void (*BT_PrintFunc)(int len, char* key);
  45.  
  46. static void IntPrint(int /* kLen */, char* key)
  47. {
  48.     fprintf(stderr, "%d", *((int*) key));
  49. }
  50.  
  51. #endif /* BT_DEBUG */
  52.  
  53.  
  54.  
  55. void redoLHash(LOGRECORDHDR* recHdr)
  56. {    
  57.     redoLHash_fr(recHdr);
  58. }
  59.  
  60. void redoLHash_fr(LOGRECORDHDR* recHdr)
  61. {
  62.  
  63.     TRPRINT(TR_IO|TR_LOG, TR_LEVEL_1, ("lsn:%d", recHdr->recordLSN.offset));
  64.  
  65.     PID* pid = & recHdr->actionPid;
  66.     TRPRINT(TR_IO|TR_LOG, TR_LEVEL_2, ("pid:%d", pid->page));
  67.  
  68.     //
  69.     //    Check to see if the operation needs to be redone
  70.     //
  71.     GROUPLINK* gLink;
  72.     if (!redoCheckPage(recHdr, &gLink, PAGE_INDEX))  {
  73.         //
  74.         //    Don't need to redo
  75.         //
  76.         TRPRINT(TR_RECOVER, TR_LEVEL_2, ("dirty page not present"));
  77.         return;
  78.         }
  79.     CHECK_GROUPLINK_MAGIC(gLink);
  80.  
  81.     LHDIRPAGE* dirp = (LHDIRPAGE*) gLink->bufFrame;
  82.     LHINDPAGE* indp = (LHINDPAGE*) gLink->bufFrame;
  83.  
  84.     //
  85.     //    redo 
  86.     //
  87.     void* vptr = GET_LOG_IMAGE(recHdr, 0);
  88.     LH_TRACE(("R(%d,%d): ", recHdr->recordLSN.offset, pid->page));
  89.     
  90.     switch (recHdr->action)  {
  91.         BT_Tuple* tp;
  92.         BT_Tuple tmp;
  93.         int keyExists;
  94.         TWO slot;
  95.         int i;
  96.         
  97.  
  98.         case LOG_ACTION_LHASH_DIRPAGE_INIT:
  99.                 {
  100.                 LogDirPageInitData* rp = (LogDirPageInitData*) vptr;
  101.                 LH_TRACE(("redo directory page init for pid %d\n", pid->page));
  102.                 dirp->Init(*pid, rp->rootFlag, rp->keyType);
  103.                 }
  104.                 break;
  105.                 
  106.         case LOG_ACTION_LHASH_INDEXPAGE_INIT:
  107.                 {
  108.                 LogIndexPageInitData* rp = (LogIndexPageInitData*) vptr;
  109.                 LH_TRACE(("redo index page init for pid %d\n", pid->page));
  110.                 indp->Init(*pid, rp->hashVal, rp->keyType, rp->ovFlag);
  111.                 }
  112.                 break;
  113.                 
  114.         case LOG_ACTION_LHASH_PHYSIC_INSERT:
  115.                 {
  116.                 LogLhashPhysicInsertData* rp =
  117.                                         (LogLhashPhysicInsertData*) vptr;
  118.                 ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
  119.                 char* buff = rp->data;
  120.                 LH_TRACE(("redo index page physic insert in page: %d", pid->page));
  121.                 for (i = rp->startSlot; i < rp->startSlot+rp->numSlots; i++)  {
  122.                     tp = (BT_Tuple*) buff;
  123.                     LH_TRACE((" %d", * (int*) tp->KeyValue()));
  124.                     indp->InsertTuple(*tp, i);
  125.                     buff += tp->Size();
  126.                     }
  127.                 if (!indp->OvLabel())
  128.                     indp->SetLoad(indp->LoadComp());
  129.                 LH_TRACE(("\n"));
  130.                 }
  131.                 break;
  132.                 
  133.         case LOG_ACTION_LHASH_PHYLOG_INSERT:
  134.                 {
  135.                 LogLhashPhyLogInsertData* rp =
  136.                                         (LogLhashPhyLogInsertData*) vptr;
  137.                 ASSERT3(rp->numSlots > 0);
  138.                 char* buff = rp->data;
  139.                 PFC func = SMCOMPFUNC[indp->KeyType()];
  140.  
  141.                 LH_TRACE(("redo index page physiological insert in page: %d", pid->page));
  142.                 for (i = 0; i < rp->numSlots; i++)  {
  143.                     tp = (BT_Tuple*) buff;
  144.                     LH_TRACE((" %d", * (int*) tp->KeyValue()));
  145.                     if (indp->Search(tp->KeyLen(), tp->KeyValue(), func,slot)) {
  146.                         ASSERT3(FALSE);
  147.                         }
  148.                     else {
  149.                         indp->InsertTuple(*tp, slot);
  150.                         }
  151.                     buff += tp->Size();
  152.                     }
  153.                 if (!indp->OvLabel())
  154.                     indp->SetLoad(indp->LoadComp());
  155.                 LH_TRACE(("\n"));
  156.                 }
  157.                 break;
  158.  
  159.         case LOG_ACTION_LHASH_PHYSIC_DELETE:
  160.                 {
  161.                 LogLhashPhysicDeleteData* rp =
  162.                                         (LogLhashPhysicDeleteData*) vptr;
  163.                 ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
  164.                 LH_TRACE(("redo index page physic delete in page: %d", pid->page));
  165.                 for (i = rp->startSlot + rp->numSlots - 1; 
  166.                                                 i >= rp->startSlot; i--)  {
  167.                     LH_TRACE((" %d", *(int*) indp->Tuple(i).KeyValue()));
  168.                     indp->RemoveTuple(i);
  169.                     }
  170.                 if (!indp->OvLabel())
  171.                     indp->SetLoad(indp->LoadComp());
  172.                 LH_TRACE(("\n"));
  173.                 }
  174.                 break;
  175.                 
  176.         case LOG_ACTION_LHASH_PHYLOG_DELETE:
  177.                 {
  178.                 LogLhashPhyLogDeleteData* rp =
  179.                                         (LogLhashPhyLogDeleteData*) vptr;
  180.                 ASSERT3(rp->numSlots > 0);
  181.                 char* buff = rp->data;
  182.                 PFC func = SMCOMPFUNC[indp->KeyType()];
  183.  
  184.                 LH_TRACE(("redo index page physiological delete in page: %d", pid->page));
  185.                 for (i = 0; i < rp->numSlots; i++)  {
  186.                     tp = (BT_Tuple*) buff;
  187.                     LH_TRACE((" %d", * (int*) tp->KeyValue()));
  188.                     if (!indp->Search(tp->KeyLen(), tp->KeyValue(), func,slot)){
  189.                         ASSERT3(FALSE);
  190.                         }
  191.                     else {
  192.                         indp->RemoveTuple(slot);
  193.                         }
  194.                     buff += tp->Size();
  195.                     }
  196.                 if (!indp->OvLabel())
  197.                     indp->SetLoad(indp->LoadComp());
  198.                 LH_TRACE(("\n"));
  199.                 }
  200.                 break;
  201.  
  202.         case LOG_ACTION_LHASH_LOGIC_INSERT:
  203.                 {
  204.                 LogLhashLogicInsertData* rp =
  205.                                         (LogLhashLogicInsertData*) vptr;
  206.                                         
  207.                 keyExists = indp->Search(rp->keyLen, rp->Key(), 
  208.                                         SMCOMPFUNC[rp->keyType],slot);
  209.                 LH_TRACE(("redo index page logic insert %d in page %d\n", 
  210.                             * (int*) rp->Key(), pid->page));
  211.                 ASSERT3(rp->elSize > 0 && rp->elSize <= SM_MAXELEMLEN);
  212.                 if (keyExists) {
  213.                     ASSERT1(!rp->unique);
  214.                     if (indp->AddElem(slot, rp->El())) {
  215.                         SM_ERROR(TYPE_FATAL, Active->errno);
  216.                         }
  217.                     }
  218.                 else {
  219.                     tmp.Create(rp->keyLen, rp->Key(), rp->El(), rp->elSize);
  220.                     indp->InsertTuple(tmp, slot);
  221.                     if (!indp->OvLabel())
  222.                         indp->SetLoad(indp->LoadComp());
  223.                     }
  224.                 ASSERT3(indp->CheckContent());
  225.                 }
  226.                 break;
  227.                     
  228.                 
  229.         case LOG_ACTION_LHASH_LOGIC_DELETE:
  230.                 {
  231.                 LogLhashLogicDeleteData* rp =
  232.                                         (LogLhashLogicDeleteData*) vptr;
  233.                                         
  234.                 keyExists = indp->Search(rp->keyLen, rp->Key(), 
  235.                                         SMCOMPFUNC[rp->keyType],slot);
  236.                 
  237.                 LH_TRACE(("redo index page logic delete %d in page %d\n", 
  238.                             * (int*) rp->Key(), pid->page));
  239.                 ASSERT1(keyExists);
  240.                 ASSERT3(indp->Tuple(slot).KeyLen() == rp->keyLen);
  241.                 ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->Key(), 
  242.                             rp->keyLen, indp->Tuple(slot).KeyValue()) == 0);
  243.                 ASSERT3( rp->elSize > 0 && rp->elSize <= SM_MAXELEMLEN);
  244.                 if (indp->RemoveElem(slot, rp->El()))  {
  245.                     SM_ERROR(TYPE_FATAL, Active->errno);
  246.                     }
  247.                 if (indp->Tuple(slot).ElCnt() == 0)  {
  248.                     indp->RemoveTuple(slot);
  249.                     if (!indp->OvLabel())
  250.                         indp->SetLoad(indp->LoadComp());
  251.                     }
  252.                 ASSERT3(indp->CheckContent());
  253.                 }
  254.                 break;
  255.                 
  256.         case LOG_ACTION_LHASH_SET_INDEX_OVERFLOW:
  257.                 {
  258.                 LogSetIndexOverflowData* rp =
  259.                                         (LogSetIndexOverflowData*) vptr;
  260.                 LH_TRACE(("redo set index page overflow in page %d\n", pid->page));
  261.                 indp->SetPageOverflow(rp->newOvPage);
  262.                 }
  263.                 break;
  264.                 
  265.         case LOG_ACTION_LHASH_RESET_INDEX_OVERFLOW:
  266.                 {
  267.                 LogResetIndexOverflowData* rp =
  268.                                         (LogResetIndexOverflowData*) vptr;
  269.                 LH_TRACE(("redo reset index page overflow in page %d\n", pid->page));
  270.                 indp->ResetPageOverflow(rp->keepFlag);
  271.                 }
  272.                 break;
  273.                 
  274.         case LOG_ACTION_LHASH_DIR_UPDATE:
  275.                 {
  276.                 LogDirUpdateData* rp = (LogDirUpdateData*) vptr;
  277.                 LH_TRACE(("redo directory page split update in page %d\n", pid->page));
  278.                 if (rp->growFlag)
  279.                     dirp->IndSplitUpdate(rp->oldFromLoad, rp->fromLoad,
  280.                                             rp->toLoad);
  281.                 else
  282.                     dirp->IndShrinkUpdate(rp->fromLoad, rp->toLoad,
  283.                                             rp->oldFromLoad);
  284.                 }
  285.                 break;
  286.  
  287.         case LOG_ACTION_LHASH_DIR_LOAD_UPDATE:
  288.                 {
  289.                 LogDirLoadUpdateData* rp =
  290.                                         (LogDirLoadUpdateData*) vptr;
  291.                 LH_TRACE(("redo directory page load update in page %d\n", pid->page));
  292.                 dirp->LoadUpdate(rp->load1,rp->load2);
  293.                 }
  294.                 break;
  295.  
  296.         case LOG_ACTION_LHASH_DIR_SET_NEXT_ENTRY:
  297.                 {
  298.                 LogDirSetNextEntryData* rp =
  299.                                         (LogDirSetNextEntryData*) vptr;
  300.                 LH_TRACE(("redo directory page set next entry in page %d hval %d\n", pid->page, rp->hashVal));
  301.                 if (rp->newPage==NULLPID-1) {
  302.                     dirp->UnSetNextEntry(rp->hashVal);
  303.                     }
  304.                 else {
  305.                     if (rp->hashVal < dirp->CurPos())
  306.                         dirp->SetEntry(rp->newPage, rp->hashVal);
  307.                     else
  308.                         dirp->SetNextEntry(rp->newPage);
  309.                     }
  310.                 }
  311.                 break;
  312.  
  313.         case LOG_ACTION_LHASH_DIR_ROOT_CTRL:
  314.                 {
  315.                 LogDirRootCtrlData* rp = (LogDirRootCtrlData*) vptr;
  316.                 LH_TRACE(("redo directory page update ctrl in page %d\n", pid->page));
  317.                 dirp->lhDirCtrl.M = rp->M;
  318.                 dirp->lhDirCtrl.P = rp->P;
  319.                 dirp->lhDirCtrl.I = rp->I;
  320.                 dirp->lhDirCtrl.curPos = rp->curPos;
  321.                 dirp->lhDirCtrl.height = rp->height;
  322.                 dirp->lhDirCtrl.load = rp->load;
  323.                 }
  324.                 break;
  325.  
  326.         case LOG_ACTION_LHASH_SET_THRESHOLD:
  327.                 {
  328.                 LogSetThresholdData* rp = (LogSetThresholdData*) vptr;
  329.                 dirp->SetThreshold(rp->newThreshold);
  330.                 }
  331.                 break;
  332.  
  333.         case LOG_ACTION_LHASH_DIR_SPLIT_COPY:
  334.                 {
  335.                 LogDirSplitData* rp =
  336.                                         (LogDirSplitData*) vptr;
  337.                 LH_TRACE(("redo directory page split copy in page %d\n", pid->page));
  338.                 dirp->lhDirCtrl.height = (ONE) rp->height;
  339.                 dirp->lhDirCtrl.curPos = rp->curPos;
  340.                 BCOPY(rp->data, dirp->indPid,
  341.                     (int)rp->curPos*sizeof(SHORTPID));
  342.                 }
  343.                 break;
  344.  
  345.         case LOG_ACTION_LHASH_DIR_SPLIT_RESET:
  346.                 {
  347.                 LogDirSplitData* rp =
  348.                                         (LogDirSplitData*) vptr;
  349.                 LH_TRACE(("redo directory page split reset in page %d\n", pid->page));
  350.                 dirp->DirSplitUpdate();
  351.                 dirp->SetNextEntry(rp->newPage1);
  352.                 dirp->SetNextEntry(rp->newPage2);
  353.                 }
  354.                 break;
  355.  
  356.         case LOG_ACTION_LHASH_LOGIC_INCR_OIDCNT:
  357.                 {
  358.                 LogLhashLogicIncrElCntData* rp =
  359.                     (LogLhashLogicIncrElCntData*) vptr;
  360.  
  361.                 keyExists = indp->Search(rp->keyLen, rp->Key(),
  362.                 SMCOMPFUNC[rp->keyType],slot);
  363.                 ASSERT1(keyExists);
  364.                 ASSERT3(indp->Tuple(slot).KeyLen() == rp->keyLen);
  365.                 ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->Key(), 
  366.                     rp->keyLen, indp->Tuple(slot).KeyValue()) == 0);
  367.                 LH_TRACE(("redo ++oidcnt\n"));
  368.                 indp->Tuple(slot).IncrElCnt();
  369.                 }
  370.                 break;
  371.  
  372.         case LOG_ACTION_LHASH_LOGIC_DECR_OIDCNT:
  373.                 {
  374.                 LogLhashLogicDecrElCntData* rp =
  375.                     (LogLhashLogicDecrElCntData*) vptr;
  376.  
  377.                 keyExists = indp->Search(rp->keyLen, rp->Key(),
  378.                 SMCOMPFUNC[rp->keyType],slot);
  379.                 ASSERT1(keyExists);
  380.                 ASSERT3(indp->Tuple(slot).KeyLen() == rp->keyLen);
  381.                 ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->Key(), rp->
  382.                 keyLen, indp->Tuple(slot).KeyValue()) == 0);
  383.  
  384.                 LH_TRACE(("redo --oidcnt\n"));
  385.                 indp->Tuple(slot).DecrElCnt();
  386.                 }
  387.                 break;
  388.  
  389.         case LOG_ACTION_LHASH_LOGIC_SET_OVERFLOW:
  390.                 {
  391.                 LogLhashLogicSetOverflowData* rp =
  392.                     (LogLhashLogicSetOverflowData*) vptr;
  393.  
  394.                 keyExists = indp->Search(rp->keyLen, rp->KeyValue(),
  395.                 SMCOMPFUNC[rp->keyType], slot);
  396.                 ASSERT1(keyExists);
  397.                 tp = & indp->Tuple(slot);
  398.                 ASSERT3(tp->KeyLen() == rp->keyLen);
  399.                 ASSERT3(tp->ElCnt() == rp->numEl);
  400.                 ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->KeyValue(),
  401.                 rp->keyLen, tp->KeyValue()) == 0);
  402.                 LH_TRACE(("redo set overflow\n"));
  403.                 indp->SetOverflow(slot, rp->ovPid);
  404.                 }
  405.                 break;
  406.  
  407.         case LOG_ACTION_LHASH_LOGIC_RESET_OVERFLOW:
  408.                 {
  409.                 LogLhashLogicSetOverflowData* rp =
  410.                     (LogLhashLogicSetOverflowData*) vptr;
  411.  
  412.                 keyExists = indp->Search(rp->keyLen, rp->KeyValue(),
  413.                 SMCOMPFUNC[rp->keyType], slot);
  414.                 ASSERT1(keyExists);
  415.                 tp = & indp->Tuple(slot);
  416.                 ASSERT3(tp->KeyLen() == rp->keyLen);
  417.                 ASSERT3(tp->ElCnt() == rp->numEl);
  418.                 ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->KeyValue(),
  419.                 rp->keyLen, tp->KeyValue()) == 0);
  420.  
  421.                 LH_TRACE(("redo reset overflow\n"));
  422.                 indp->SetUnderflow(slot, rp->numEl, rp->ElList());
  423.                 }
  424.                 break;
  425.         case LOG_ACTION_LHASH_OV_CONVERT:
  426.                 {
  427.                 LogLhashOvConvertData* rp =
  428.                             (LogLhashOvConvertData*) vptr;
  429.                 LH_TRACE(("redo convert overflow in page %d\n", pid->page));
  430.                 indp->OvConvert(rp->newHashVal, rp->cvtFlag);
  431.                 }
  432.                 break;
  433.         default:                
  434.                 SM_ERROR(TYPE_FATAL, esmINTERNAL);
  435.         }
  436.     
  437.     if (recHdr->action == LOG_ACTION_LHASH_DIR_UPDATE ||
  438.        recHdr->action == LOG_ACTION_LHASH_DIR_LOAD_UPDATE ||
  439.        recHdr->action == LOG_ACTION_LHASH_DIRPAGE_INIT ||
  440.        recHdr->action == LOG_ACTION_LHASH_DIR_SET_NEXT_ENTRY ||
  441.        recHdr->action == LOG_ACTION_LHASH_DIR_SPLIT_COPY ||
  442.        recHdr->action == LOG_ACTION_LHASH_DIR_SPLIT_RESET ||
  443.        recHdr->action == LOG_ACTION_LHASH_DIR_ROOT_CTRL ||
  444.        recHdr->action == LOG_ACTION_LHASH_SET_THRESHOLD
  445.        ) {
  446.         dirp->lrc() = recHdr->actionLRC;
  447.         }
  448.     else    {
  449.         ASSERT3(indp->CheckContent());
  450.         indp->lrc() = recHdr->actionLRC;
  451.         }
  452.  
  453.     signalSemaphore(&gLink->pageHash->semaphore);
  454.  
  455.     bf_UnfixPage(gLink, BF_DEFAULT, TRUE);
  456. }
  457.  
  458.